
package adoc.xml;

import adoc.AdocUtilities;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.Namespace;
import org.jdom.input.SAXBuilder;

/**
 *
 * @author ILikePancakes
 */
public class ManifestDocument extends Document {
    private Element root;
    private Namespace namespace = Namespace.getNamespace("manifest", "urn:oasis:names:tc:opendocument:xmlns:manifest:1.0");
    public static final String METADATA_FOLDER = "application/vnd.lt.archyvai.adoc-2008#metadata-folder";

    public ManifestDocument() {
        super();
        root = new Element("manifest");
        root.setNamespace(namespace);
        this.setRootElement(root);
    }

    public ManifestDocument(String mainDocument, String[] appendices, HashMap<String, ArrayList> appendixMap, String[] attachments, String[] metadata, String[] METAINF) {
        this();
        addFileEntry("/", AdocUtilities.MIMETYPE_ADOC);
        addFileEntry(AdocUtilities.getFileName(mainDocument), AdocUtilities.getRealMimeType(mainDocument));
        if (appendices != null) {
            addFileEntry("priedai/", "");
            for (int i = 0; i < appendices.length; i++) addFileEntry("priedai/" + AdocUtilities.getFileName(appendices[i]), AdocUtilities.getRealMimeType(appendices[i]));
            for (ArrayList appendixList : appendixMap.values()) {
                for (Object appendix : appendixList) {
                    addFileEntry("priedai/"+AdocUtilities.getFileName((String) appendix), AdocUtilities.getRealMimeType((String) appendix));
                }
            }
        }
        if (attachments != null) {
            addFileEntry("pridedami/", "");
            for (int i = 0; i < attachments.length; i++) addFileEntry("pridedami/" + AdocUtilities.getFileName(attachments[i]), AdocUtilities.MIMETYPE_ADOC);
        }
        if (metadata != null) {
            addFileEntry("metadata/", METADATA_FOLDER);
            for (int i = 0; i < metadata.length; i++) addFileEntry(metadata[i].replace('\\', '/'), AdocUtilities.MIMETYPE_XML);
        }
        if (METAINF != null) {
            addFileEntry("META-INF/", "");
            for (int i = 0; i < METAINF.length; i++) {
                if (!AdocUtilities.getFileName(METAINF[i]).equals("manifest.xml")) addFileEntry(METAINF[i].replace('\\', '/'), AdocUtilities.MIMETYPE_XML);
            }
        }
    }

    public ManifestDocument(File file) throws IOException, JDOMException {
        super(new SAXBuilder().build(file).cloneContent());
        root = this.getRootElement();
    }

    public ManifestDocument(String filename) throws IOException, JDOMException {
        this(new File(filename));
    }

    public Element addFileEntry(String fullPath, String mediaType) {
        Element fileEntry = new Element("file-entry");
        fileEntry.setAttribute("full-path", fullPath, namespace);
        fileEntry.setAttribute("media-type", mediaType, namespace);
        fileEntry.setNamespace(namespace);
        root.addContent(fileEntry);
        return fileEntry;
    }

    public String getType(String filename) {
        for (Element e : fileEntries()) {
            if (e.getAttributeValue("full-path", e.getNamespace()).equals((filename))) {
                return e.getAttributeValue("media-type", e.getNamespace());
            }
        }
        return null;
    }

    public List<Element> fileEntries() {
        return root.getChildren();
    }

    public ArrayList<String> fileNames() {
        ArrayList<String> filenames = new ArrayList();
        for (Element e : fileEntries()) {
            filenames.add(e.getAttributeValue("full-path", e.getNamespace()));
        }
        return filenames;
    }

    public ArrayList<String> directoryNames() {
        ArrayList<String> dirnames = new ArrayList();
        for (Element e : fileEntries()) {
            String path = e.getAttributeValue("full-path", e.getNamespace());
            if (path.endsWith("/")) dirnames.add(path);
        }
        return dirnames;
    }

    public int entryCount() { return root.getChildren().size(); }

    public int fileCount() {
        int count = 0;
        for (String filename : this.fileNames()) { if (!filename.endsWith("/")) count++; }
        return count;
    }

    public int directoryCount() {
        int count = 0;
        for (String filename : this.fileNames()) { if (filename.endsWith("/")) count++; }
        return count;
    }

}
